﻿//////////////////////////////////////////////////////////////////
//
// ITerrain.cs
//
// Copyright (c) 2012 Dan Pike.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation files
// (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Interfaces
{
   /// <summary>
   /// Constants that relate to the processing of terrains.
   /// These are declared as a member of the special class
   /// named '_' so that they can be used in expressions and
   /// still look a little bit like numbers, yet allow for
   /// refactoring etc, if it ever proves necessary to change
   /// their value. This reduces the amount of "noise" in
   /// expressions that would otherwise require very long
   /// and descriptive constants
   /// </summary>
   public partial class Const
   {
      /// <summary>
      /// The number of points per row/column in the SRTM .overlapped file
      /// </summary>
      public const int srtmRow3602 = 3602;

      /// <summary>
      /// Offset of the final row/column in the SRTM .overlapped file
      /// </summary>
      public const int srtmRow3601 = srtmRow3602 - 1;

      /// <summary>
      /// The number of "active" vertices in a single tile row/column, not including
      /// the overlap at either end
      /// </summary>
      public const int srtm3600 = srtmRow3602 - 2;

      /// <summary>
      /// The number of cells along the edge of a single tile (one arc-minute)
      /// (note that tiles are square)
      /// </summary>
      public const int tileWidth60 = 60;

      /// <summary>
      /// The number of cells along the edge of a single tile (one arc-minute)
      /// (note that tiles are square) PLUS ONE
      /// </summary>
      public const int tileWidth61 = 61;

      /// <summary>
      /// The number of cells along the edge of a single tile (one arc-minute)
      /// (note that tiles are square) PLUS TWO
      /// </summary>
      public const int tileWidth62 = 62;

      /// <summary>
      /// The width in arc-seconds of a single tile
      /// </summary>
      public const float tileWidthSeconds60 = 60.0f;

      /// <summary>
      /// Scale factor for translating from elevation in metres to "graphical units"
      /// 
      /// Assume each cell is 1.0fx1.0fx1.0f in Xna space and there are 60x60 cells
      /// in each tile. Each square in the x & y directions represents one arc second
      /// on the earth which corresponds to 11.12m. To keep proportions, we therefore
      /// divide the height values (z direction) by 11.12
      /// </summary>
      public const float heightScale11pt12 = 11.12f;

      /// <summary>
      /// The size of a bounding box
      /// 1. Must be a factor of tile width, so that there are a whole number of boxes
      ///    in each tile
      /// 2. Must be an even number so that the bottom-left cell in in a t-strip that
      ///    goes from "left-right" in the normal x-y orientation (alternate rows of
      ///    triangles in the same strip go in opposite directions).
      /// </summary>
      public const int cellsPerBox = 6;

      /// <summary>
      /// The number of bounding boxes in each direction in a tile
      /// (the length of each dimension in the TerrainHolder.boundingBoxes_ array)
      /// </summary>
      public const int boxCount10 = tileWidth60 / cellsPerBox;
   }

   /// <summary>
   ///
   /// </summary>
   public interface ITerrain
   {
      ////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// Initialize the terrain-generator using the specified address
      /// </summary>
      /// <param name="planetName"></param>
      /// <returns></returns>
      bool Initialize(string planetName);

      ////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// Load the given tile into the cache (if necessary) and return the
      /// heights array for it
      /// </summary>
      /// <param name="location">Points somewhere in the required tile</param>
      short[,] LoadTile(ILocation location);

      ////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// Update the cache with new image data for the tile
      /// </summary>
      /// <param name="location">Points somewhere in the required tile</param>
      void TileImage(ILocation location, short[,] heights);

      ////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// Download the given tile from the server (if necessary) and return the
      /// heights array for it
      /// </summary>
      /// <param name="location">Points somewhere in the required tile</param>
      short[,] DownloadTile(ILocation location);
   }
}
